package org.iteam.bank.signed.action;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.iteam.bank.mina.utils.ConfigLoader;
import org.iteam.bank.mina.utils.HexUtils;
import org.iteam.bank.mina.utils.IpUtils;
import org.iteam.bank.signed.model.Bank;
import org.iteam.bank.signed.model.BankCardBin;
import org.iteam.bank.signed.model.BankRegion;
import org.iteam.bank.signed.model.P2PUserInfo;
import org.iteam.bank.signed.service.BankCardBinService;
import org.iteam.bank.signed.service.BankRegionService;
import org.iteam.bank.signed.service.GSPService;
import org.iteam.bank.signed.service.P2PUserService;
import org.iteam.bank.signed.service.SignedService;
import org.iteam.commons.codec.AESCoder;
import org.iteam.commons.codec.HMACCoder;
import org.iteam.db.exception.DbException;
import org.iteam.mina.Constant;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;

@SuppressWarnings("unchecked")
@Results({ @Result(type = "freemarker", name = "index", location = "/WEB-INF/content/platform/verification-bank.html") })
public class SignedAction extends BaseAction {
	private static final long serialVersionUID = -556897203680426494L;

	private static final String defaultBankCode = "33";// 默认银行
	private static final String defaultBankCardType = "DEBIT";// 支持的银行卡类型
	private static final String SESSION_SIGNED_CARD_INFO = "SESSION_SIGNED_CARD_INFO";// 绑卡用户基础信息
	private String signedParams;// 绑卡加密参数
	private String signedSign;// 绑卡加密签名
	protected String mobile;// 手机号
	protected String p2p_user_id;// 手机号
	private String cardholderNo;// 银行卡号
	private String cardholderName;// 持卡人姓名
	private String bankType;// 银行类型
	private String bankName;// 银行名称
	private String idCard;// 身份证件号码1
	private String captcha;// 验证码
	private String seqCode;// 验证码序号
	private String province;// 省份
	private String city;// 城市
	private String bankBranchNo;// 联行号
	private String bankBranchName;// 联行名称

	@Action("/signed")
	public String signed() {
		init();
		logger.debug("接收绑卡请求:signedParams={}", signedParams);
		logger.debug("接收绑卡请求:signedSign={}", signedSign);
		try {
			// 验证签名
			byte[] content = HexUtils.decodeHexByte(signedParams);
			byte[] oldSign = HexUtils.decodeHexByte(signedSign);
			// bindCard.KEY_HMAC
			// bindCard.KEY_AES
			byte[] sign = HMACCoder.encryptHMAC(content, ConfigLoader.get("signed.KEY_HMAC"));
			if (Arrays.equals(sign, oldSign)) {
				// 签名验证成功，进入解密流程
				byte[] eContent = AESCoder.decrypt(content, ConfigLoader.get("signed.KEY_AES"));
				JSONObject params = JSON.parseObject(new String(eContent, Constant.UTF_8));
				logger.debug("接收绑卡请求:bindParams[解密后]={}", params.toJSONString());
				String p2p_user_id = params.getString("p2p_user_id");
				// params.getIntValue("accountType");
				// params.getString("notifyUrl");
				// params.getString("callBack");
				if (StringUtils.isBlank(p2p_user_id)) {
					map.put("gotoURL", ConfigLoader.get("PC_URL"));
					return "error";
				}
				P2PUserInfo info = P2PUserService.getInstance().showById(p2p_user_id);
				map.put("info", info);
				map.put("p2p_user_id", p2p_user_id);
				if (info == null) {
					return signedError(ConfigLoader.get("PC_URL"), "绑卡信息验证错误，请重试", "文创汇");
				} else {
					// 2审核中 1为已认证，0为未认证，默认为0
					switch (info.getCardNoStatus().intValue()) {
					case 2:
						return signedWarn(ConfigLoader.get("PC_URL"), "您的绑卡请求正在处理中，请勿重复绑卡", "文创汇");
					case 1:
						return signedWarn(ConfigLoader.get("PC_URL"), "您已经绑卡，请勿重复绑卡", "文创汇");
					case 0:
						break;
					default:
						break;
					}

				}
				session.put(SESSION_SIGNED_CARD_INFO.concat(p2p_user_id), params.toJSONString());
			}
			map.put("banks", BankCardBinService.getInstance().queryAll());
		} catch (DbException e) {
			logger.error(e.getMessage(), e);
			return signedError(ConfigLoader.get("PC_URL"), "绑卡信息验证错误，请重试", "文创汇");
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			return signedError(ConfigLoader.get("PC_URL"), "绑卡信息验证错误，请重试", "文创汇");
		}
		return "index";
	}

	/**
	 * 银行卡类型验证
	 * 
	 * @return
	 */

	@Action("/signed/bank/cardflag")
	public String cardflag() {
		try {
			BankCardBin bankCardBin = BankCardBinService.getInstance().showByCardFlag(cardholderNo);
			if (bankCardBin != null) {
				Map<String, String> bankCodes = new HashMap<String, String>();
				Map<String, String> bankNames = new HashMap<String, String>();
				List<Bank> banks = BankCardBinService.getInstance().queryAll();
				for (Bank bank : banks) {
					bankCodes.put(bank.getId(), bank.getCode());
					bankNames.put(bank.getCode(), bank.getName());
				}
				boolean support = bankCodes.containsKey(bankCardBin.getBank_id());
				map.put("support", support);
				map.put("bankName", bankCardBin.getBank_name());
				map.put("bankCode", bankCodes.get(bankCardBin.getBank_id()));
				boolean isDebit = support && defaultBankCardType.equalsIgnoreCase(bankCardBin.getCard_type());
				map.put("isDebit", isDebit);
				if (!support) {
					map.put("state", false);
					map.put("info", "尚不支持" + bankCardBin.getBank_name());
				} else {
					if (support && !isDebit) {
						map.put("state", false);
						map.put("info", "仅支持借记卡");
					} else {
						map.put("state", true);
						map.put("info", "成功");
					}
				}
			} else {
				map.put("support", false);// 是否支持该银行
				map.put("isDebit", false);// 是否是借记卡
				map.put("bankCode", defaultBankCode);
				map.put("state", false);
				map.put("info", "该银行尚不支持");
			}

		} catch (DbException e) {
			logger.error(e.getMessage(), e);
			map.put("state", false);
			map.put("info", "系统繁忙,请稍候重试");
		}
		return MAP;
	}

	/**
	 * 银行卡类型验证
	 * 
	 * @return
	 */
	@Action("/signed/bank/cardflagValidate")
	public String cardflagValidate() {
		try {
			if (StringUtils.isNotBlank(cardholderNo) && cardholderNo.length() >= 6) {
				cardholderNo = cardholderNo.substring(0, 6);
				BankCardBin bankCardBin = BankCardBinService.getInstance().showByCardFlag(cardholderNo);
				Map<String, String> bankCodes = new HashMap<String, String>();
				Map<String, String> bankNames = new HashMap<String, String>();
				List<Bank> banks = BankCardBinService.getInstance().queryAll();
				for (Bank bank : banks) {
					bankCodes.put(bank.getId(), bank.getCode());
					bankNames.put(bank.getCode(), bank.getName());
				}
				boolean support = bankCodes.containsKey(bankCardBin.getBank_id());
				boolean isDebit = support && defaultBankCardType.equalsIgnoreCase(bankCardBin.getCard_type());
				object = support && isDebit;
			} else {
				object = false;
			}
		} catch (DbException e) {
			logger.error(e.getMessage(), e);
			object = false;
		}
		return OBJECT;
	}

	/**
	 * 身份证号码存在验证
	 * 
	 * @return
	 */
	@Action("/signed/bank/idCardValidate")
	public String idCardValidate() {
		try {
			if (StringUtils.isNotBlank(idCard)) {
				object = !P2PUserService.getInstance().existUserByIdCard(idCard);
			} else {
				object = true;
			}
		} catch (DbException e) {
			logger.error(e.getMessage(), e);
			object = true;
		}
		return OBJECT;
	}

	/**
	 * 加载地区
	 * 
	 * @return
	 */
	@Action("/signed/bank/city")
	public String loadCity() {
		try {
			Map<String, Map<String, Object>> data = new HashMap<String, Map<String, Object>>();
			List<BankRegion> list = BankRegionService.getInstance().queryAll();
			for (BankRegion bankRegion : list) {
				Map<String, Object> row = null;
				if ("0".equals(bankRegion.getParent_id())) {
					if (data.containsKey(bankRegion.getId())) {
						row = data.get(bankRegion.getId());
					} else {
						row = new HashMap<String, Object>();
						data.put(bankRegion.getId(), row);
					}
					row.put("id", bankRegion.getId());
					row.put("parent_id", bankRegion.getParent_id());
					row.put("code", bankRegion.getCode());
					row.put("region_name", bankRegion.getRegion_name());
				} else {
					if (data.containsKey(bankRegion.getParent_id())) {
						row = data.get(bankRegion.getParent_id());
					}
					List<Map<String, Object>> child = null;
					if (row.containsKey("child")) {
						child = (List<Map<String, Object>>) row.get("child");
					} else {
						child = new ArrayList<Map<String, Object>>();
						row.put("child", child);
					}
					Map<String, Object> childRow = new HashMap<String, Object>();
					childRow.put("id", bankRegion.getId());
					childRow.put("parent_id", bankRegion.getParent_id());
					childRow.put("code", bankRegion.getCode());
					childRow.put("region_name", bankRegion.getRegion_name());
					child.add(childRow);
				}
			}
			map = data;
		} catch (DbException e) {
			logger.error(e.getMessage(), e);
		}
		return MAP;
	}

	/**
	 * 发送绑定银行卡验证码
	 * 
	 * @return
	 */

	@Action("/signed/bank/captcha")
	public String sendBingdCaptcha() {
		try {
			String serialNo = GSPService.getInstance().sendCaptcha(mobile);
			if (StringUtils.isNotBlank(serialNo)) {
				map.put("state", true);
				map.put("serialNo", serialNo);
				map.put("info", "发送成功");
			} else {
				map.put("state", false);
				map.put("info", "验证码发送失败,请稍候重试");
			}

		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			map.put("state", false);
			map.put("info", "系统繁忙,请稍候重试");
		}
		return MAP;
	}

	@Action("/signed/bank/searchBank")
	public String searchBank() {
		try {
			if (StringUtils.isNotBlank(bankName)) {
				bankName = bankName.replaceAll(" ", "%");
			}
			JSONObject res = GSPService.getInstance().searchBankName(bankName);
			map.put("state", true);
			map.put("data", res);
			map.put("info", "发送成功");
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			map.put("state", false);
			map.put("info", "系统繁忙,请稍候重试");
		}

		return MAP;
	}

	@Action("/signed/bank/bind")
	public String bindBankCard() {
		logger.debug("用户绑卡参数:{}", JSON.toJSONString(request.getParameterMap()));
		try {

			JSONObject params = JSON.parseObject(session.get(SESSION_SIGNED_CARD_INFO.concat(p2p_user_id)).toString());
			String p2p_user_id = params.getString("p2p_user_id");
			// params.getIntValue("accountType");
			// params.getString("notifyUrl");
			// params.getString("callBack");

			// 验证身份证号码
			// 01：判断参数
			// 02:判断该银行卡号的银行类型和卡片类型是否支持
			// 03:判断是否是本行或者它行卡
			// 04:调用绑卡接口(本行/它行)
			// 05：判断操作结果
			boolean result = true;
			// 判断参数
			if (result && StringUtils.isBlank(cardholderName)) {
				map.put("state", false);
				map.put("info", "姓名不能为空");
				result = false;
			}
			if (result && StringUtils.isBlank(cardholderNo)) {
				map.put("state", false);
				map.put("info", "银行卡号不能为空");
				result = false;
			}
			if (result && StringUtils.isBlank(bankType)) {
				map.put("state", false);
				map.put("info", "银行类型不能为空");
				result = false;
			}
			if (result && StringUtils.isBlank(idCard)) {
				map.put("state", false);
				map.put("info", "身份证号不能为空");
				result = false;
			}
			P2PUserInfo info = P2PUserService.getInstance().showById(p2p_user_id);

			if (result && P2PUserService.getInstance().existUserByIdCard(idCard)) {
				map.put("state", false);
				map.put("info", "该身份证已经签约");
				result = false;
			}
			if (result && P2PUserService.getInstance().existUserByCardno(cardholderNo)) {
				map.put("state", false);
				map.put("info", "该银行卡已经签约");
				result = false;
			}
			if (result && info.getCardNoStatus().intValue() == 1) {
				map.put("state", false);
				map.put("info", "您已经签约银行卡");
				result = false;
			}
			if (result && info.getCardNoStatus().intValue() == 2) {
				map.put("state", false);
				map.put("info", "银行卡签约绑定中,请勿重复绑定");
				result = false;
			}

			if (result && StringUtils.isBlank(mobile)) {
				map.put("state", false);
				map.put("info", "银行预留手机号不能为空");
				result = false;
			}
			if (result && StringUtils.isBlank(captcha)) {
				map.put("state", false);
				map.put("info", "验证码不能为空");
				result = false;
			}
			Map<String, String> bankCodes = new HashMap<String, String>();
			Map<String, String> bankNames = new HashMap<String, String>();
			List<Bank> banks = BankCardBinService.getInstance().queryAll();
			for (Bank bank : banks) {
				bankCodes.put(bank.getId(), bank.getCode());
				bankNames.put(bank.getCode(), bank.getName());
			}
			// 验证选择的银行类型是否支持
			if (result && !bankNames.containsKey(bankType)) {
				map.put("state", false);
				map.put("info", "该银行尚不支持");
				result = false;
			}

			// 验证 银行卡号 是否支持
			if (result) {
				BankCardBin bankCardBin = BankCardBinService.getInstance().showByCardFlag(cardholderNo.substring(0, 6));
				if (bankCardBin != null) {
					boolean support = bankCodes.containsKey(bankCardBin.getBank_id());
					if (support) {
						boolean isDebit = defaultBankCardType.equalsIgnoreCase(bankCardBin.getCard_type());
						if (!isDebit) {
							map.put("state", false);
							map.put("info", "仅支持储蓄卡");
							result = false;
						}
					} else {
						map.put("state", false);
						map.put("info", "尚不支持" + bankCardBin.getBank_name());
						result = false;
					}
				} else {
					map.put("state", false);
					map.put("info", "该银行尚不支持");
					result = false;
				}
				if (result) {
					String baseBankType = bankCodes.get(bankCardBin.getBank_id());
					if (!bankType.equals(baseBankType)) {
						map.put("state", false);
						map.put("info", "银行卡号与银行卡类型不匹配");
						result = false;
					}
				}
			}
			// 是否是农商行
			boolean isRCB = true;
			// 他行卡验证参数
			if (result && !defaultBankCode.equals(bankType)) {
				isRCB = false;
				if (result && StringUtils.isBlank(bankBranchName)) {
					map.put("state", false);
					map.put("info", "开户支行不能为空");
					result = false;
				}
				if (result && StringUtils.isBlank(bankBranchNo)) {
					map.put("state", false);
					map.put("info", "开户支行不能为空");
					result = false;
				}
				if (result && StringUtils.isBlank(province)) {
					map.put("state", false);
					map.put("info", "开户地不能为空");
					result = false;
				}
				if (result && StringUtils.isBlank(city)) {
					map.put("state", false);
					map.put("info", "开户地不能为空");
					result = false;
				}
			}
			if (isRCB) {
				bankBranchNo = null;
				bankBranchName = null;
			}
			if (result) {
				StringBuffer msg = new StringBuffer();
				// 开始绑定银行卡
				int bankResult = SignedService.getInstance().bindCard(p2p_user_id, mobile, cardholderNo, cardholderName, bankType, bankName, idCard, captcha,
						seqCode, province, city, bankBranchNo, bankBranchName, isRCB, IpUtils.ip(request), msg);
				map.put("state", false);
				map.put("bankResult", bankResult);
				map.put("bankResult", bankResult);
				switch (bankResult) {
				case -1:
					if (msg.length() == 0) {
						msg.append("绑卡失败,请稍候重试");
					}
					map.put("info", msg.toString());
					break;
				case 0:
					map.put("info", "您的账户已绑定银行卡");
					break;
				case 1:
					map.put("callBack", params.getString("callBack"));
					map.put("state", true);
					map.put("info", "银行卡绑定成功");
					break;
				case 2:
					map.put("info", "绑卡处理中,请稍候查询处理结果");
					break;
				default:
					map.put("info", "绑卡失败,请稍候重试");
					break;
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage(), e);
			map.put("state", false);
			map.put("info", "系统异常,请稍候重试");
		}
		logger.debug("绑卡结果:{}", JSON.toJSONString(map));
		return MAP;
	}

	public String getCardholderNo() {
		return cardholderNo;
	}

	public void setCardholderNo(String cardholderNo) {
		this.cardholderNo = cardholderNo;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}

	public String getCardholderName() {
		return cardholderName;
	}

	public void setCardholderName(String cardholderName) {
		this.cardholderName = cardholderName;
	}

	public String getBankType() {
		return bankType;
	}

	public void setBankType(String bankType) {
		this.bankType = bankType;
	}

	public String getBankName() {
		return bankName;
	}

	public void setBankName(String bankName) {
		this.bankName = bankName;
	}

	public String getIdCard() {
		return idCard;
	}

	public void setIdCard(String idCard) {
		this.idCard = idCard;
	}

	public String getCaptcha() {
		return captcha;
	}

	public void setCaptcha(String captcha) {
		this.captcha = captcha;
	}

	public String getSeqCode() {
		return seqCode;
	}

	public void setSeqCode(String seqCode) {
		this.seqCode = seqCode;
	}

	public String getProvince() {
		return province;
	}

	public void setProvince(String province) {
		this.province = province;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getBankBranchNo() {
		return bankBranchNo;
	}

	public void setBankBranchNo(String bankBranchNo) {
		this.bankBranchNo = bankBranchNo;
	}

	public String getBankBranchName() {
		return bankBranchName;
	}

	public void setBankBranchName(String bankBranchName) {
		this.bankBranchName = bankBranchName;
	}

	public String getSignedParams() {
		return signedParams;
	}

	public void setSignedParams(String signedParams) {
		this.signedParams = signedParams;
	}

	public String getSignedSign() {
		return signedSign;
	}

	public void setSignedSign(String signedSign) {
		this.signedSign = signedSign;
	}

	public String getP2p_user_id() {
		return p2p_user_id;
	}

	public void setP2p_user_id(String p2p_user_id) {
		this.p2p_user_id = p2p_user_id;
	}

	
}